package com.magicrule.car.systemManage.configClass.shiro;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

import com.magicrule.car.systemManage.model.Role;
import com.magicrule.car.systemManage.model.RoleResourcePermission;
import com.magicrule.car.systemManage.model.User;
import com.magicrule.car.systemManage.service.api.UserServiceApi;

/**
 * 
 * @ClassName: AuthRealm
 * @Description:TODO(shiro自定义Realm)
 * @author: hebb
 * @date: 2018年12月7日 下午10:24:49
 * 
 * @Copyright: 2018 www.magicruler.com Inc. All rights reserved.
 *             注意：本内容仅限于魔尺信息技术有限公司内部传阅，禁止外泄以及用于其他的商业目的
 */
public class AuthRealm extends AuthorizingRealm {

	protected static Logger log = LoggerFactory.getLogger(AuthRealm.class);

	@Autowired
	@Lazy
	private UserServiceApi userServiceApi;

	/**
	 * 
	 * @Title: doGetAuthorizationInfo   
	 * @Description: TODO(获取用户的权限信息)    
	 * @param principals
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		Set<String> resourcePermissionList = new HashSet<String>();
		Set<String> roleNameList=new HashSet<String>();
		
		User user = (User) principals.getPrimaryPrincipal();
		List<Role> roleList = userServiceApi.getRoleListByUserId(user.getId());
		if(roleList!=null && roleList.size()>0) {
			for(Role role:roleList) {
				roleNameList.add(role.getRoleName());
			}
		}
		
		List<RoleResourcePermission> roleResourcePermiessionList = userServiceApi.getPermissionsByRoleList(roleList);
		if (roleResourcePermiessionList != null && roleResourcePermiessionList.size() > 0) {
			for (RoleResourcePermission roleResourcePermission : roleResourcePermiessionList) {
				resourcePermissionList.add(roleResourcePermission.getResourcePermission());
			}
		}

		// 将权限放入shiro中
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		authorizationInfo.setRoles(roleNameList);
		authorizationInfo.setStringPermissions(resourcePermissionList);
		return authorizationInfo;
	}

	/**
	 * 
	 * @Title: doGetAuthenticationInfo   
	 * @Description: TODO(用户身份验证)    
	 * @param token
	 * @return
	 * @throws AuthenticationException
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 获取基于用户名和密码的令牌
		// 实际上这个token是从LoginController里面currentUser.login(token)传过来的
		UsernamePasswordToken utoken = (UsernamePasswordToken) token;
		String userName = utoken.getUsername();
		User user = userServiceApi.getUserByUserName(userName);

		if (user != null) {
			this.setSession("currentUser", user);
			// 放入shiro中，然后调用CredentialMather来检验密码
			return new SimpleAuthenticationInfo(user, user.getPassword(),
					ByteSource.Util.bytes(user.getCredentialsSalt()), this.getClass().getName());
		} else {
			return null;
		}
	}

	private void setSession(Object key, Object value) {
		Subject subject = SecurityUtils.getSubject();
		if (null != subject) {
			Session session = subject.getSession();
			if (null != session) {
				session.setAttribute(key, value);
			}
		}
	}

}
